package com.jgame.secondarymarket.infrastructure.common.model.response;

import com.jgame.secondarymarket.infrastructure.common.constants.ResultMessageConstants;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Consumer;

/**
 * @title: Result
 * @Author Wangsj
 * @Date: 2021/7/16
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
@ApiModel("返回结果")
public class Result<T> {

    private Integer code;
    private String msg;
    private T data;


    public static Result ok() {
        return ok(null);
    }

    public static <T> Result<T> ok(T t) {
        return ok(t, ResultMessageConstants.MSG_SUCCESS);
    }

    public static <T> Result<T> ok(T t, String msg) {
        return Result.<T>builder().data(t).code(0).msg(msg).build();
    }


    public static <T> Result<T> error() {
        return error(-1);
    }

    public static <T> Result<T> error(Integer code) {
        return error(code, ResultMessageConstants.MSG_ERROR);
    }

    public static <T> Result<T> error(String msg) {
        return error(-1, msg);
    }

    public static <T> Result<T> error(Integer code, String msg) {
        return error(null, code, msg);
    }

    public static <T> Result<T> error(T t, Integer code, String msg) {
        return Result.<T>builder().data(t).code(code).msg(msg).build();
    }


    /**
     * 执行操作，并根据操作是否成功返回给客户端相应信息
     * 封装了在服务端接口中很常见的执行操作，成功返回成功标志、失败返回失败标志的通用操作，用于简化编码
     */
    public static Result op(Runnable executor) {
        return op(executor, e -> log.error(e.getMessage(), e));
    }

    /**
     * 执行操作（带自定义的失败处理），并根据操作是否成功返回给客户端相应信息
     * 封装了在服务端接口中很常见的执行操作，成功返回成功标志、失败返回失败标志的通用操作，用于简化编码
     */
    public static Result op(Runnable executor, Consumer<Exception> exceptionConsumer) {
        try {
            executor.run();
            return Result.ok();
        } catch (Exception e) {
            exceptionConsumer.accept(e);
            return Result.error(e.getMessage());
        }
    }

}
